﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Web.Hosting;
using UDS.Components;

namespace UDS.Entity
{
    /// <summary>
    /// An attachment for a document. The data is stored in table UDS_Flow_Files.
    /// </summary>
    public class DocumentFile
    {
        #region AttachDir & TempAttachDir

        private static string s_attachDir;

        /// <summary>
        /// Gets the virtual directory where the attachment files are stored.
        /// </summary>
        public const string AttachVDir = @"~\Files\DocumentFlow\AttachFiles\";

        public const string TempAttachVDir = AttachVDir + @"tmp\";

        /// <summary>
        /// Gets the physical path to the directory where the attachment files are stored.
        /// </summary>
        public static string AttachDir
        {
            get
            {
                if (s_attachDir == null)
                {
                    var dir = HostingEnvironment.MapPath(AttachVDir);
                    if (string.IsNullOrEmpty(dir))
                    {
                        throw new InvalidOperationException("The attachment directory cannot be found.");
                    }
                    s_attachDir = dir;
                }

                return s_attachDir;
            }
        }

        public static string TempAttachDir
        {
            get { return AttachDir + @"tmp\"; }
        }

        #endregion

        #region properties

        /// <summary>
        /// 文件ID
        /// </summary>
        public int FileID
        {
            get;
            set;
        }

        /// <summary>
        /// 文档ID
        /// </summary>
        public int DocID
        {
            get;
            set;
        }

        /// <summary>
        /// 文件名
        /// </summary>
        public string FileName
        {
            get;
            set;
        }

        /// <summary>
        /// 文件大小
        /// </summary>
        public long FileSize
        {
            get;
            set;
        }

        /// <summary>
        /// 文件属性
        /// </summary>
        public int FileAttribute
        {
            get;
            set;
        }

        /// <summary>
        /// 文件虚拟路径
        /// </summary>
        public string FileVisualPath
        {
            get;
            set;
        }

        /// <summary>
        /// Get the full virtual path of this file.
        /// </summary>
        public string FullVirtualPath
        {
            get { return Utility.CombineVirtualDirs(FileVisualPath, FileName); }
        }

        /// <summary>
        /// 文件作者
        /// </summary>
        public string Author
        {
            get;
            set;
        }

        /// <summary>
        /// 文件类别
        /// </summary>
        public string Catalog
        {
            get;
            set;
        }

        /// <summary>
        /// 文件添加日期
        /// </summary>
        public DateTime TimeCreated
        {
            get;
            set;
        }

        #endregion

        public static IList<DocumentFile> GetAttachments(int docId)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@DocID", SqlDbType.Int, 4, docId)
            };

            var db = new Database();
            var list = new List<DocumentFile>();
            using (var dr = db.RunDataReader("dbo.sproc_Flow_GetDocumentAttach_V2", parameters))
            {
                while (dr.Read())
                {
                    list.Add(ReadFile(dr, false));
                }
            }

            return list;
        }

        /// <summary>
        /// 获得公文附件路径
        /// </summary>
        public static string GetAttachmentPath(int docId)
        {
            var db = new Database();
            return GetAttachmentPath(docId, db);
        }

        public static string GetAttachmentPath(int docId, Database db)
        {
            Debug.Assert(db != null);
            var parameters = new[]
            {
                Database.MakeInParam("@DocID", SqlDbType.Int, 4, docId)
            };

            using (var dr = db.RunDataReader("dbo.sproc_Flow_GetDocumentAttach_V2", parameters))
            {
                if (dr.Read())
                {
                    var file = ReadFile(dr, false);
                    return Utility.CombineVirtualDirs(file.FileVisualPath, file.FileName);
                }
            }

            return null;
        }

        /// <summary>
        /// 添加文件附件数据库操作
        /// </summary>
        /// <returns>
        /// The id of the newly created file.
        /// </returns>
        internal static int AddAttach(Database db, DocumentFile file)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@DocID", SqlDbType.Int, 4, file.DocID),
                Database.MakeInParam("@FileName", SqlDbType.NVarChar, 300, file.FileName),
                Database.MakeInParam("@FileSize", SqlDbType.Int, 4, file.FileSize),
                Database.MakeInParam("@FileAttribute", SqlDbType.Int, 4, file.FileAttribute),
                Database.MakeInParam("@FileVisualPath", SqlDbType.NVarChar, 200, file.FileVisualPath),
                Database.MakeInParam("@FileAuthor", SqlDbType.NVarChar, 50, file.Author),
                Database.MakeInParam("@FileCatlog", SqlDbType.NVarChar, 20, file.Catalog),
                Database.MakeInParam("@FileAddedDate", SqlDbType.DateTime, 30, file.TimeCreated)
            };
            return db.RunProc("dbo.sproc_Flow_AddFile_V2", parameters);
        }

        /// <summary>
        /// 添加文件批注附件
        /// </summary>
        internal static void AddPostilAttach(Database db, DocumentFile file, int postilID)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@PostilID", SqlDbType.Int, 20, postilID),
                Database.MakeInParam("@FileName", SqlDbType.NVarChar, 300, file.FileName),
                Database.MakeInParam("@FileSize", SqlDbType.Int, 4, file.FileSize),
                Database.MakeInParam("@FileAttribute", SqlDbType.Int, 4, file.FileAttribute),
                Database.MakeInParam("@FileVisualPath", SqlDbType.NVarChar, 200, file.FileVisualPath),
                Database.MakeInParam("@FileAuthor", SqlDbType.NVarChar, 50, file.Author),
                Database.MakeInParam("@FileCatlog", SqlDbType.NVarChar, 20, file.Catalog),
                Database.MakeInParam("@FileAddedDate", SqlDbType.DateTime, 0, file.TimeCreated)
            };

            int id = db.RunProc("dbo.sproc_Flow_AddPostilFile_V2", parameters);
            if (id <= 0)
            {
                throw new InvalidOperationException("Failed to create an attachment.");
            }
        }

        internal static DocumentFile ReadFile(IDataReader dr, bool allowNull)
        {
            object fileId = dr["FileID"];
            if (fileId == null || fileId == DBNull.Value)
            {
                if (allowNull)
                {
                    return null;
                }
                throw new InvalidOperationException("FileID is missing.");
            }

            var f = new DocumentFile();
            f.FileID = (int)fileId;
            f.DocID = (int)dr["DocID"];
            f.FileName = Convert.ToString(dr["FileName"]);
            f.FileSize = Utility.ReadInt32(dr["FileSize"], 0);
            f.FileAttribute = Utility.ReadInt32(dr["FileAttribute"], 0);
            f.FileVisualPath = Convert.ToString(dr["FileVisualPath"]);
            f.Author = Convert.ToString(dr["FileAuthor"]);
            f.Catalog = Convert.ToString(dr["FileCatlog"]);
            f.TimeCreated = Utility.ReadSQLDate(dr["FileAddedDate"]);
            return f;
        }
    }
}
